package com.ieng.kican.modules.security.service;

import com.ieng.kican.api.model.User;
import com.ieng.kican.common.exception.VerifyException;
import com.ieng.kican.common.groups.captcha.CaptchaCation;
import com.ieng.kican.common.utils.IDUtils;
import com.ieng.kican.common.utils.IUtil;
import com.ieng.kican.modules.security.config.properties.LoginProperties;
import com.ieng.kican.modules.cache.RedisCache;
import com.ieng.kican.modules.security.domain.Token;
import com.ieng.kican.modules.security.domain.Verification;
import com.ieng.kican.modules.security.group.TokenProvider;
import com.ieng.kican.modules.security.utils.SecurityUtils;
import com.ieng.kican.modules.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class AuthorizationService {
    @Autowired
    private AuthenticationManagerBuilder managerBuilder;
    @Autowired
    private LoginProperties loginProperties;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserService userService;
    @Autowired
    private TokenProvider tokenProvider;

    /**
     * 验证
     *
     * @param uuid 唯一标识
     * @param code 验证码
     * @return boolean
     */
    public boolean verify(String uuid, String code) {
        Verification verification = redisCache.getObject(loginProperties.getSessionName() + uuid);
        if (!IUtil.isNotObject(verification)) {
            throw new VerifyException("验证码不存在或已过期");
        }
        return code.equalsIgnoreCase(verification.getText());
    }

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @return Token
     */
    public Token login(String username, String password) {
        User user = userService.findByUsername(username);
        if (IUtil.isNotObject(user) && SecurityUtils.matchesPass(user.getPassword(), password)) {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            Authentication authentication = managerBuilder.getObject().authenticate(authenticationToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            String token = tokenProvider.createToken(authentication);
            // 登录在线逻辑...
            return new Token(token);
        }
        return null;
    }

    /**
     * 生成Base64验证码
     *
     * @return Map uuid,text
     */
    public Map<String, String> generateCode() {
        CaptchaCation.Action action = CaptchaCation.base64(loginProperties);
        String uuid = IDUtils.simpleUUID();
        // 生成的验证码信息存入Redis
        Verification verification = new Verification(uuid, action.getText());
        redisCache.setObject(loginProperties.getSessionName() + uuid, verification, loginProperties.getExpiredTime().toMinutes(), TimeUnit.MINUTES);
        // 唯一标识,验证码图片(Base64)
        Map<String, String> map = new HashMap<>(2);
        map.put("uuid", uuid);
        map.put("text", action.getBase64());
        return map;
    }

}
